﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MyHome.Server.PluginBase;
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;

namespace MyHome.ServerPluginTests
{
    [TestClass]
    public class BaseTest
    {
        [TestInitialize]
        public void Initialize()
        {
            Trace.Listeners.Add(new ConsoleTraceListener());
        }

        [TestMethod]
        public async Task TestInput()
        {
            var input = new TestInputPlugin.TestInputPlugin();

            Assert.IsNull(input.Configuration);
            Assert.AreEqual(-1, input.Id);
            Assert.IsNull(input.LastValue);
            Assert.AreEqual(PluginType.Input, input.PluginType);
            Assert.AreEqual(PluginState.Stopped, input.State);

            await input.StartAsync();

            Assert.AreEqual(PluginState.Running, input.State);
        }

        [TestMethod]
        public async Task TestConsoleOutput()
        {
            var output = new ConsoleOutputPlugin.ConsoleOutputPlugin();

            Assert.IsNull(output.Configuration);
            Assert.AreEqual(-1, output.Id);
            Assert.AreEqual(PluginType.Output, output.PluginType);
            Assert.AreEqual(PluginState.Stopped, output.State);

            await output.StartAsync();

            Assert.AreEqual(PluginState.Running, output.State);
        }

        [TestMethod]
        public async Task TestProcessing()
        {
            var processing = new TestProcessingPlugin.TestProcessingPlugin();

            Assert.IsNull(processing.Configuration);
            Assert.AreEqual(-1, processing.Id);
            Assert.AreEqual(PluginType.Processing, processing.PluginType);
            Assert.AreEqual(PluginState.Stopped, processing.State);

            await processing.StartAsync();

            Assert.AreEqual(PluginState.Running, processing.State);
        }

        [TestMethod]
        public async Task TestSimpleConnection()
        {
            var input = new TestInputPlugin.TestInputPlugin();
            var output = new ConsoleOutputPlugin.ConsoleOutputPlugin();
            var connection = new MyHome.Server.PluginBase.PluginConnection<object>();

            await input.StartAsync();
            await output.StartAsync();

            Assert.IsNull(connection.Input);
            Assert.IsNull(connection.Output);
            Assert.AreEqual(-1, connection.Id);

            connection.Input = input;
            connection.Output = output;

            Assert.AreEqual(input, connection.Input);
            Assert.AreEqual(output, connection.Output);

            for (int i = 0; i < 10; i++)
            {
                input.SendValue(i);
            }

            input.SendValue(null);
            input.SendValue(new object());
        }

        [TestMethod]
        public async Task TestProcessingConnection()
        {
            var input = new TestInputPlugin.TestInputPlugin();
            var output = new ConsoleOutputPlugin.ConsoleOutputPlugin();
            var processing = new TestProcessingPlugin.TestProcessingPlugin();
            var connection = new MyHome.Server.PluginBase.PluginConnection<object>();
            var connection2 = new MyHome.Server.PluginBase.PluginConnection<object>();

            await input.StartAsync();
            await output.StartAsync();
            await processing.StartAsync();

            connection.Input = input;
            connection.Output = processing;
            connection2.Input = processing;
            connection2.Output = output;

            for (int i = 0; i < 10; i++)
            {
                input.SendValue(i);
            }

            input.SendValue(null);
            input.SendValue(new object());
        }
    }
}
